package com.ztrue.framework.context;

import com.ztrue.framework.core.domain.IAggregateRootCache;
import com.ztrue.framework.core.domain.IAggregateStorage;
import com.ztrue.framework.core.domain.IRepository;
import com.ztrue.framework.core.domain.impl.AggregateRootCache;
import com.ztrue.framework.core.domain.impl.DefaultRepository;
import com.ztrue.framework.core.domain.impl.EventSourcingAggregateStorage;
import com.ztrue.framework.core.event.IEventStore;
import com.ztrue.framework.core.event.impl.MongoDBEventStore;
import com.ztrue.framework.handler.DefaultHandlerRegistry;
import com.ztrue.framework.handler.IHandlerDefinitionRegistry;
import com.ztrue.framework.handler.IHandlerRegistry;
import com.ztrue.framework.handler.SimpleHandlerDefinitionRegistry;
import com.ztrue.framework.infrastructure.impl.DefaultClassProvider;

/**
 * 应用程序上下文抽象
 *
 * @author zhangw
 * @date 2016/11/16 15:22
 * @version: 1.0
 */
public abstract class AbstractApplicationContext {
    protected IHandlerDefinitionRegistry handlerDefinitionRegistry;
    protected IHandlerRegistry handlerRegistry;
    protected IEventStore eventStore;
    protected IAggregateStorage aggregateStorage;
    protected IAggregateRootCache aggregateRootCache;
    protected IRepository repository;
    protected IAggregateRootInternalHandlerProvider aggregateRootInternalHandlerProvider;
    protected String SCANSEPARATOR = ";";

    /**
     * 初始化资源
     */
    abstract void init();

    public AbstractApplicationContext() {
        this.handlerDefinitionRegistry = makeHandlerDefinitionRegistry();
        this.handlerRegistry = makeHandlerRegistry();
        this.repository = makeRepository();
        this.aggregateRootInternalHandlerProvider = makeAggregateRootInternalHandlerProvider();
        init();
    }

    /**
     * 生成处理器定义注册表
     *
     * @return
     */
    protected IHandlerDefinitionRegistry makeHandlerDefinitionRegistry() {
        return new SimpleHandlerDefinitionRegistry();
    }

    /**
     * 生成处理器注册表
     *
     * @return
     */
    protected IHandlerRegistry makeHandlerRegistry() {
        return new DefaultHandlerRegistry(this.handlerDefinitionRegistry);
    }

    /**
     * 生成一个聚合根存储库
     *
     * @return
     */
    protected IRepository makeRepository() {
        return new DefaultRepository(makeaAggregateRootCache(), makeAggregateStorage());
    }

    /**
     * 生成一个领域事件内部处理器提供者
     *
     * @return
     */
    protected IAggregateRootInternalHandlerProvider makeAggregateRootInternalHandlerProvider() {
        return new DefaultAggregateRootInternalHandlerProvider(this.handlerDefinitionRegistry, this.aggregateRootCache);
    }

    /**
     * 生成一个聚合根缓存对象
     *
     * @return
     */
    protected IAggregateRootCache makeaAggregateRootCache() {
        this.aggregateRootCache = new AggregateRootCache();
        return aggregateRootCache;
    }

    /**
     * 生成事件源聚合存储
     *
     * @return
     */
    protected IAggregateStorage makeAggregateStorage() {
        this.aggregateStorage = new EventSourcingAggregateStorage(makeEventStore(), new DefaultClassProvider());
        return aggregateStorage;
    }

    /**
     * 生成一个领域事件存储
     *
     * @return
     */
    protected IEventStore makeEventStore() {
        this.eventStore = new MongoDBEventStore();
        return eventStore;
    }

    /**
     * 获取处理器定义注册表
     *
     * @return
     */
    IHandlerDefinitionRegistry getHandlerDefinitionRegistry() {
        return this.handlerDefinitionRegistry;
    }

    /**
     * 获取处理器注册表
     *
     * @return
     */
    IHandlerRegistry getHandlerRegistry() {
        return this.handlerRegistry;
    }

    /**
     * 获取领域事件存储
     *
     * @return
     */
    IEventStore getEventStore() {
        return eventStore;
    }

    /**
     * 获取聚合存储
     *
     * @return
     */
    IAggregateStorage getAggregateStorage() {
        return aggregateStorage;
    }

    /**
     * 获取聚合根缓存
     *
     * @return
     */
    IAggregateRootCache getAggregateRootCache() {
        return aggregateRootCache;
    }

    /**
     * 获取领域事件内部处理器提供者
     *
     * @return
     */
    IAggregateRootInternalHandlerProvider getAggregateRootInternalHandlerProvider() {
        return this.aggregateRootInternalHandlerProvider;
    }

    /**
     * 获取聚合根存储库
     *
     * @return
     */
    IRepository getRepository() {
        return repository;
    }
}